From 76e5a428e1ee8dc1772aea9cf4c53c8f6068ea85 Mon Sep 17 00:00:00 2001 From: "kfraser@dhcp93.uk.xensource.com" Date: Thu, 29 Jun 2006 16:59:47 +0100 Subject: [PATCH] [XEN] Fix the timeout workaround so it doesn't capture negative diffs relative to current time. Signed-off-by: Keir Fraser --- xen/common/schedule.c | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/xen/common/schedule.c b/xen/common/schedule.c index cb80104016..cc9947e279 100644 --- a/xen/common/schedule.c +++ b/xen/common/schedule.c @@ -389,30 +389,30 @@ long do_sched_op(int cmd, XEN_GUEST_HANDLE(void) arg) long do_set_timer_op(s_time_t timeout) { struct vcpu *v = current; + s_time_t offset = timeout - NOW(); if ( timeout == 0 ) { stop_timer(&v->timer); } + else if ( unlikely(timeout < 0) || /* overflow into 64th bit? */ + unlikely((offset > 0) && ((uint32_t)(offset >> 50) != 0)) ) + { + /* + * Linux workaround: occasionally we will see timeouts a long way in + * the future due to wrapping in Linux's jiffy time handling. We check + * for timeouts wrapped negative, and for positive timeouts more than + * about 13 days in the future (2^50ns). The correct fix is to trigger + * an interrupt immediately (since Linux in fact has pending work to + * do in this situation). + */ + DPRINTK("Warning: huge timeout set by domain %d (vcpu %d):" + " %"PRIx64"\n", + v->domain->domain_id, v->vcpu_id, (uint64_t)timeout); + send_timer_event(v); + } else { - if ( unlikely(timeout < 0) || - unlikely((uint32_t)((timeout - NOW()) >> 50) != 0) ) - { - /* - * Linux workaround: occasionally we will see timeouts a long way - * in the future due to wrapping in Linux's jiffy time handling. - * We check for tiemouts wrapped negative, and for positive - * timeouts more than about 13 days in the future (2^50ns). - * The correct fix is to trigger an interrupt in a short while - * (since Linux in fact has pending work to do in this situation). - */ - DPRINTK("Warning: huge timeout set by domain %d (vcpu %d):" - " %"PRIx64"\n", - v->domain->domain_id, v->vcpu_id, (uint64_t)timeout); - timeout = NOW() + MILLISECS(10); - } - set_timer(&v->timer, timeout); } -- 2.30.2